import type {RequestOptions} from '@@/plugin-request/request';
import type {RequestConfig} from '@umijs/max';
import {history} from '@umijs/max';
import {message, notification} from 'antd';
import {getAuthToken} from '@/utils/auth';
import {DEFAULT_LOGIN_PATH as LOGIN_PATH} from 'kf-web-library';
import lodash from "lodash";
import React from "react";

// 接口code类型
const codeMessage = {
    200: '服务器成功返回请求的数据。',
    201: '新建或修改数据成功。',
    202: '一个请求已经进入后台排队（异步任务）。',
    204: '删除数据成功。',
    400: '发出的请求有错误，参数错误。',
    401: '用户没有权限。',
    403: '用户得到授权，但是访问是被禁止的。',
    404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
    406: '请求的格式不可得。',
    410: '请求的资源被永久删除，且不会再得到的。',
    422: '当创建一个对象时，发生一个验证错误。',
    500: '服务器发生错误，请检查服务器。',
    502: '网关错误。',
    503: '服务不可用，服务器暂时过载或维护。',
    504: '网关超时。',
};

// 与后端约定的响应数据格式
interface ResponseStructure {
    readonly timestamp: string;
    readonly bizcode: number;
    readonly code: number;
    readonly flag: boolean;
    readonly path?: string;
    readonly msg?: string;
    readonly query?: string;
    readonly status?: string;
    readonly data: any;
}

/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const errorConfig: RequestConfig = {
    errorConfig: {
        // 错误抛出
        errorThrower: (res) => {
            //看看是否是业务错误（HttpStatus为200,但是响应body中flag标识为失败的）
            const {flag, msg, bizcode, code, data} = res as unknown as ResponseStructure;
            if (!flag) {
                const error: any = new Error(msg);
                error.name = 'BizError';
                error.info = {code, bizcode, msg, data};
                throw error; // 抛出业务错误
            }
        },
        // 错误接收及处理
        errorHandler: (error: any, opts: any) => {
            if (opts?.skipErrorHandler) {
                throw error;
            }

            // errorThrower 抛出的业务错误。
            if (error.name === 'BizError') {
                const errorInfo: ResponseStructure | undefined = error.info;
                if (errorInfo) {
                    const {code, bizcode, msg} = errorInfo;
                    message.error(msg);
                }
            } else if (error.response) {
                // Axios 的错误
                // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
                const {status: httpStatusCode, statusText, data: respData} = error.response;
                const {code, bizcode, msg = error.code} = respData || {};
                switch (httpStatusCode) {
                    case 401:
                        message.error('未登陆或登陆已过时，请重新登陆！');
                        history.push(LOGIN_PATH);
                        break;
                    case 400:
                    case 410:
                      const errorText = respData.msg || codeMessage[httpStatusCode] || statusText;
                      if(respData.bizcode && respData.bizcode === 400002){
                        let errorDetailText: React.ReactNode = '';
                        if (lodash.isObject(respData.data)) {
                          errorDetailText = Object.entries(respData.data).map((entry, entryIndex) => {
                            return (
                              <div key={entryIndex}>
                                <span>{entry[0]}: </span><span>{entry[1] as string}</span>
                              </div>
                            );
                          });
                        } else {
                          errorDetailText = respData.data && respData.data.toString();
                        }
                        notification.error({
                          //message: `请求错误 ${status}: ${url}`,
                          message: errorText,
                          description: errorDetailText && (
                            <div>
                              <div>{errorDetailText}</div>
                            </div>
                          ),
                        });
                      }else{
                        message.error(errorText);
                      }
                        break;
                    default:
                        message.error(msg);
                }
            } else if (error.request) {
                // 请求已经成功发起，但没有收到响应
                // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
                // 而在node.js中是 http.ClientRequest 的实例
                message.error('None response! Please retry.');
            } else {
                // 发送请求时出了点问题
                message.error('Request error, please retry.');
            }
        },
    },
    // 请求拦截器
    requestInterceptors: [
        (config: RequestOptions) => {
            //如果有认证token将其写入到Header中的Authorization中去
            const authToken = getAuthToken();
            if (authToken) {
                const headers = {...config.headers, Authorization: `Bearer ${authToken}`};
                return {...config, headers};
            }
            return config;
        },
    ],
    // 响应拦截器
    responseInterceptors: [],
};
